/*
 *
 * This file is part of the open-source SeetaFace engine, which includes three modules:
 * SeetaFace Detection, SeetaFace Alignment, and SeetaFace Identification.
 *
 * This file is part of the SeetaFace Detection module, containing codes implementing the
 * face detection method described in the following paper:
 *
 *
 *   Funnel-structured cascade for multi-view face detection with alignment awareness,
 *   Shuzhe Wu, Meina Kan, Zhenliang He, Shiguang Shan, Xilin Chen.
 *   In Neurocomputing (under review)
 *
 *
 * Copyright (C) 2016, Visual Information Processing and Learning (VIPL) group,
 * Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China.
 *
 * The codes are mainly developed by Shuzhe Wu (a Ph.D supervised by Prof. Shiguang Shan)
 *
 * As an open-source face recognition engine: you can redistribute SeetaFace source codes
 * and/or modify it under the terms of the BSD 2-Clause License.
 *
 * You should have received a copy of the BSD 2-Clause License along with the software.
 * If not, see < https://opensource.org/licenses/BSD-2-Clause>.
 *
 * Contact Info: you can send an email to SeetaFace@vipl.ict.ac.cn for any problems.
 *
 * Note: the above information must be kept whenever or wherever the codes are used.
 *
 */

#ifndef SEETA_FD_CLASSIFIER_LAB_BOOSTED_CLASSIFIER_H_
#define SEETA_FD_CLASSIFIER_LAB_BOOSTED_CLASSIFIER_H_

//#include <algorithm>
//#include <memory>

#include "classifier.h"
#include "lab_feature_map.h"

/**
 * @class LABBaseClassifier
 * @brief Base classifier using LAB feature.
 */
 static const int32_t kFeatGroupSize = 10;
static const float kStdDevThresh = 10.0f;

typedef struct classLABBaseClassifier LABBaseClassifier;
struct classLABBaseClassifier {
	
  int32_t num_bin_;
  float* weights_;
  float thresh_;

 
};
void ReleaseLABBaseClassifier(struct classLABBaseClassifier *p);
void LABBaseClassifierSetWeights(struct classLABBaseClassifier *p, const float* weights, int32_t num_bin);

//void InitLABBaseClassifier(struct classLABBaseClassifier *p, int num_bin = 255, float thresh = 0.0f); 
void InitLABBaseClassifier(struct classLABBaseClassifier *p, int num_bin , float thresh );
void LABBaseClassifierSetThreshold(struct classLABBaseClassifier *p, float thresh);

int32_t LABBaseClassifiernum_bin(struct classLABBaseClassifier *p);
float LABBaseClassifierweights(struct classLABBaseClassifier *p, int32_t val);
float LABBaseClassifierthreshold(struct classLABBaseClassifier *p);
/**
 * @class LABBoostedClassifier
 * @Brief A strong classifier constructed from base classifiers using LAB features.
 */
typedef struct classLABBoostedClassifier LABBoostedClassifier;
//class LABBoostedClassifier : public Classifier {
struct classLABBoostedClassifier{
  LABFeature feat_[150];
  LABBaseClassifier base_classifiers_[150];
  LABFeatureMap feat_map_;
  bool use_std_dev_;

  float* base_thresh;
  float* base_weights;
  int32_t* feat_x;
  int32_t* feat_y;
  Classifier classifier;
};
void ReleaseLABBoostedClassifier(struct classLABBoostedClassifier *p);
//bool LABBoostedClassifierClassify(LABBoostedClassifier *p, LABFeatureMap* feat_map,float* score = nullptr, float* outputs = nullptr);
bool LABBoostedClassifierClassify(LABBoostedClassifier *p, LABFeatureMap* feat_map, float* score , float* outputs );
void LABBoostedClassifierAddFeature(struct classLABBoostedClassifier *p, int32_t x, int32_t y,int n);
void LABBoostedClassifierAddFeatureGPU(struct classLABBoostedClassifier *p, int32_t x, int32_t y, int num_classifer_);
void LABBoostedClassifierAddBaseClassifier(struct classLABBoostedClassifier *p, const float* weights, int32_t num_bin, float thresh,int n);

void LABBoostedClassifierFeatInitGPU(struct classLABBoostedClassifier *p, int weight_len, int num_base_classifer_);
void LABBoostedClassifierAddBaseClassifierGPU(struct classLABBoostedClassifier *p, const float* weights,int32_t num_bin, float thresh,int num_classifer_, int n);

float* LABBoostedClassifierGet_base_threshold(struct classLABBoostedClassifier *p);
float* LABBoostedClassifierGet_base_weights(struct classLABBoostedClassifier *p);
int32_t* LABBoostedClassifierGet_feat_x(struct classLABBoostedClassifier *p);
int32_t* LABBoostedClassifierGet_feat_y(struct classLABBoostedClassifier *p);
int LABBoostedClassifierclassifierSize(struct classLABBoostedClassifier *p);
int LABBoostedClassifierFeatGroupSize(struct classLABBoostedClassifier *p);

void InitLABBoostedClassifier(struct classLABBoostedClassifier *p);
int LABBoostedClassifiertype(struct classLABBoostedClassifier *p);
void LABBoostedClassifierSetFeatureMap(struct classLABBoostedClassifier *p, LABFeatureMap* featMap);

 void LABBoostedClassifierSetUseStdDev(struct classLABBoostedClassifier *p, bool useStdDev);




#endif  // SEETA_FD_CLASSIFIER_LAB_BOOSTED_CLASSIFIER_H_
